﻿using System.Diagnostics;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

public class Program
{
    public static void Main(string[] args)
    {
        //var program = new Program();
        //var result1 = program.OriginalCode();
        //var result2 = program.OptimizedCode1();
        //var result3 = program.OptimizedCode2();

        //for (var i = 0; i < result1.Length; i++)
        //{
        //    if (string.Equals(result1[i].Name, result2[i].Name))
        //    {

        //    }
        //    else
        //    {
        //        Debugger.Break();
        //    }

        //    if (string.Equals(result1[i].Name, result3[i].Name))
        //    {

        //    }
        //    else
        //    {
        //        Debugger.Break();
        //    }
        //}

        BenchmarkRunner.Run<Program>();
    }



    [Benchmark(Baseline = true)]
    public AssemblyRecord[] OriginalCode()
    {
        // private static AssemblyRecord[] _records;
        AssemblyRecord[] _records;

        // create the records for each uncommon assembly
        string[] names = Enum.GetNames(typeof(UncommonAssembly));
        int n = names.Length;
        _records = new AssemblyRecord[n];

        for (int i = 0; i < n; ++i)
        {
            _records[i].Name = names[i].Replace('_', '.') + ",";  // comma delimits simple name within Assembly.FullName
        }

        return _records;
    }

    [Benchmark()]
    public AssemblyRecord[] OptimizedCode1()
    {
        // private static AssemblyRecord[] _records;
        AssemblyRecord[] _records;

        // create the records for each uncommon assembly
        string[] names = new string[]
        {
           "System.Drawing.Common,",
           "System.Private.Xml,",
           "System.Private.Xml.Linq,",
           "System.Data.Common,",
           "System.Linq.Expressions,"
        }; // Enum.GetNames(typeof(UncommonAssembly));

        int n = names.Length;
        _records = new AssemblyRecord[n];

        for (int i = 0; i < n; ++i)
        {
            _records[i].Name = names[i];  // comma delimits simple name within Assembly.FullName
        }

        return _records;
    }


    [Benchmark()]
    public AssemblyRecord[] OptimizedCode2()
    {
        // private static AssemblyRecord[] _records;
        AssemblyRecord[] _records;

        // create the records for each uncommon assembly
        // Generated by Enum.GetNames(typeof(UncommonAssembly));
        // comma delimits simple name within Assembly.FullName
        _records = new AssemblyRecord[]
        {
            new AssemblyRecord()
            {
                Name = "System.Drawing.Common,"
            },
            new AssemblyRecord()
            {
                Name = "System.Private.Xml,"
            },
            new AssemblyRecord()
            {
                Name = "System.Private.Xml.Linq,"
            },
            new AssemblyRecord()
            {
                Name = "System.Data.Common,"
            },
            new AssemblyRecord()
            {
                Name = "System.Linq.Expressions,"
            },
        };

        return _records;
    }
}

public enum UncommonAssembly
{
    // Each enum name must match the assembly name, with dots replaced by underscores
    System_Drawing_Common,
    System_Private_Xml,
    System_Private_Xml_Linq,
    System_Data_Common,
    System_Linq_Expressions,
}

public struct AssemblyRecord
{
    public string Name { get; set; }
    public bool IsLoaded { get; set; }
}